#!/bin/bash -ex

# get the values of $SNAP_DATA and $SNAP using the current symlink instead of
# the default behavior which has the revision hard-coded, which breaks after
# a refresh
SNAP_DATA_CURRENT=${SNAP_DATA/%$SNAP_REVISION/current}
SNAP_CURRENT=${SNAP/%$SNAP_REVISION/current}

# install all the config files from $SNAP/config/SERVICE/res/configuration.toml 
# into $SNAP_DATA/config
mkdir -p "$SNAP_DATA/config"
for service in edgex-mongo security-api-gateway security-secret-store core-command config-seed core-data core-metadata export-client export-distro support-logging support-notifications support-scheduler sys-mgmt-agent device-random device-virtual; do
    if [ ! -f "$SNAP_DATA/config/$service/res/configuration.toml" ]; then
        mkdir -p "$SNAP_DATA/config/$service/res"
        cp "$SNAP/config/$service/res/configuration.toml" "$SNAP_DATA/config/$service/res/configuration.toml"
        # do replacement of the $SNAP, $SNAP_DATA, $SNAP_COMMON environment variables in the config files
        sed -i -e "s@\$SNAP_COMMON@$SNAP_COMMON@g" \
            -e "s@\$SNAP_DATA@$SNAP_DATA_CURRENT@g" \
            -e "s@\$SNAP@$SNAP_CURRENT@g" \
            "$SNAP_DATA/config/$service/res/configuration.toml"
    fi
done

# handle device-random device profile
cp "$SNAP/config/device-random/res/device.random.yaml" "$SNAP_DATA/config/device-random/res/device.random.yaml"

# handle device-virtual device profiles
for profileType in bool float int uint; do
    cp "$SNAP/config/device-virtual/res/device.virtual.$profileType.yaml" "$SNAP_DATA/config/device-virtual/res/device.virtual.$profileType.yaml"
done

# also handle java services' application.properties
# shellcheck disable=SC2043
for jsvc in edgex-support-rulesengine; do
    if [ ! -f "$SNAP_DATA/config/config-seed/res/properties/$jsvc/application.properties" ]; then
        mkdir -p "$SNAP_DATA/config/config-seed/res/properties/$jsvc"
        cp "$SNAP/config/config-seed/res/properties/$jsvc/application.properties" "$SNAP_DATA/config/config-seed/res/properties/$jsvc/application.properties"
        # also replace SNAP_DATA and SNAP_COMMON in the application files
        sed -i -e "s@\$SNAP_COMMON@$SNAP_COMMON@g" -e "s@\$SNAP_DATA@$SNAP_DATA_CURRENT@g" "$SNAP_DATA/config/config-seed/res/properties/$jsvc/application.properties"
    fi
done

# create support-rulesengine directories for templates/rules
if [ ! -f "$SNAP_DATA/support-rulesengine/templates" ]; then
    mkdir -p "$SNAP_DATA/support-rulesengine/templates"
    cp "$SNAP/jar/support-rulesengine/templates/rule-template.drl" "$SNAP_DATA/support-rulesengine/templates/rule-template.drl"
fi

if [ ! -f "$SNAP_DATA/support-rulesengine/rules" ]; then
    mkdir -p "$SNAP_DATA/support-rulesengine/rules"
fi


# for security-secret-store, copy the hcl config files used with vault
for hclType in admin kong; do 
    if [ ! -f "$SNAP_DATA/config/security-secret-store/res/vault-policy-$hclType.hcl" ]; then
        mkdir -p "$SNAP_DATA/config/security-secret-store/res"
        cp "$SNAP/config/security-secret-store/res/vault-policy-$hclType.hcl" "$SNAP_DATA/config/security-secret-store/res/vault-policy-$hclType.hcl"
    fi
done

# for the kong pki setup file, we need to set the hostname as localhost
# and then set the directory to store the cert files as $SNAP_DATA/kong/ssl
if [ ! -f "$SNAP_DATA/config/security-secret-store/pkisetup-kong.json" ]; then
    mkdir -p "$SNAP_DATA/config/security-secret-store"
    CONFIG_FILE_PATH="config/security-secret-store/pkisetup-kong.json"
    # replace the hostname with localhost using jq
    jq --arg WORKDIR "$SNAP_DATA_CURRENT/vault" \
        '.x509_tls_server_parameters.tls_host = "localhost" | .pki_setup_dir = "pki" | .working_dir  = $WORKDIR' \
        "$SNAP/$CONFIG_FILE_PATH" > "$SNAP_DATA/$CONFIG_FILE_PATH.tmp"
    mv "$SNAP_DATA/$CONFIG_FILE_PATH.tmp" "$SNAP_DATA/$CONFIG_FILE_PATH"
    chmod 600 "$SNAP_DATA/config/security-secret-store/pkisetup-kong.json"
fi

# for vault, we also need to set the hostname as localhost
# and then set the directory to store the cert files as $SNAP_DATA/vault/pki
if [ ! -f "$SNAP_DATA/config/security-secret-store/pkisetup-vault.json" ]; then
    mkdir -p "$SNAP_DATA/config/security-secret-store"
    CONFIG_FILE_PATH="config/security-secret-store/pkisetup-vault.json"
    # modify the parameters using jq
    jq --arg WORKDIR "$SNAP_DATA_CURRENT/vault" \
        '.x509_tls_server_parameters.tls_host = "localhost" | .pki_setup_dir = "pki" | .working_dir  = $WORKDIR' \
        "$SNAP/$CONFIG_FILE_PATH" > "$SNAP_DATA/$CONFIG_FILE_PATH.tmp"
    mv "$SNAP_DATA/$CONFIG_FILE_PATH.tmp" "$SNAP_DATA/$CONFIG_FILE_PATH"
    chmod 600 "$SNAP_DATA/config/security-secret-store/pkisetup-vault.json"
fi

# ensure consul dirs exist
mkdir -p "$SNAP_DATA/consul/data"
mkdir -p "$SNAP_DATA/consul/config"

# ensure mongodb data dirs exist
mkdir -p "$SNAP_DATA/mongo/db"

# ensure vault pki directory exists
mkdir -p "$SNAP_DATA/vault/pki"

# touch all the kong log files to ensure they exist
mkdir -p "$SNAP_COMMON/logs"
for type in proxy admin; do
    for op in access error; do
        touch "$SNAP_COMMON/logs/kong-$type-$op.log"
    done
done

# install redis configuration files
if [ ! -f "$SNAP_DATA/config/redis/redis.conf" ]; then
    mkdir -p "$SNAP_DATA/redis"
    cp "$SNAP/config/redis/redis.conf" "$SNAP_DATA/redis/redis.conf"
    sed -i -e "s@\$SNAP_COMMON@$SNAP_COMMON@g" \
        -e "s@\$SNAP_DATA@$SNAP_DATA_CURRENT@g" \
        -e "s@\$SNAP@$SNAP_CURRENT@g" \
        "$SNAP_DATA/redis/redis.conf"
fi

# the vault config needs to be generated with sed, replacing $SNAP_DATA in the file 
# with the actual absolute directory
# note that if anyone ever somehow has a "@" in their $SNAP_DATA this will likely break :-/
if [ ! -f "$SNAP_DATA/config/security-secret-store/vault-config.hcl" ]; then
    mkdir -p "$SNAP_DATA/config/security-secret-store"
    sed "s@\$SNAP_DATA@$SNAP_DATA_CURRENT@g" "$SNAP/config/security-secret-store/vault-config.hcl.in" > "$SNAP_DATA/config/security-secret-store/vault-config.hcl"
    chmod 644 "$SNAP_DATA/config/security-secret-store/vault-config.hcl"
fi

# the kong config file needs to be generated with 3 changes from the default one included in the snap
# - we set the prefix to be $SNAP_DATA/kong as an absolute path (note that this has to be done here in the install hook)
# - we set the nginx user to be root
if [ ! -f "$SNAP_DATA/config/security-api-gateway/kong.conf" ]; then
    mkdir -p "$SNAP_DATA/config/security-api-gateway"
    cp "$SNAP/config/security-api-gateway/kong.conf" "$SNAP_DATA/config/security-api-gateway/kong.conf"
    # replace the default prefix setting with an absolute path using $SNAP_DATA
    # note that if anyone ever has a "@" in their $SNAP_DATA this will likely fail
    sed -i "s@#prefix = /usr/local/kong/@prefix = $SNAP_DATA_CURRENT/kong@" "$SNAP_DATA/config/security-api-gateway/kong.conf"

    # also replace the default nginx user/group to be root
    sed -i "s@#nginx_user = nobody nobody@nginx_user = root root@" "$SNAP_DATA/config/security-api-gateway/kong.conf"
fi

# setup postgres db config file with env vars replaced
if [ ! -f "$SNAP_DATA/etc/postgresql/10/main/postgresql.conf" ]; then
    mkdir -p "$SNAP_DATA/etc/postgresql/10/main"
    cp "$SNAP/etc/postgresql/10/main/postgresql.conf" "$SNAP_DATA/etc/postgresql/10/main/postgresql.conf"
    # do replacement of the $SNAP, $SNAP_DATA, $SNAP_COMMON environment variables in the config files
    sed -i -e "s@\$SNAP_COMMON@$SNAP_COMMON@g" \
        -e "s@\$SNAP_DATA@$SNAP_DATA_CURRENT@g" \
        -e "s@\$SNAP@$SNAP_CURRENT@g" \
        "$SNAP_DATA/etc/postgresql/10/main/postgresql.conf"
fi

# ensure the postgres data directory exists and is owned by snap_daemon
mkdir -p "$SNAP_DATA/postgresql" 
chown -R snap_daemon:snap_daemon "$SNAP_DATA/postgresql" 

# setup the postgres data directory
gosu snap_daemon "$SNAP/usr/lib/postgresql/10/bin/initdb" -D "$SNAP_DATA/postgresql/10/main"

# ensure the sockets dir exists and is properly owned
mkdir -p "$SNAP_COMMON/sockets"
chown -R snap_daemon:snap_daemon "$SNAP_COMMON/sockets" 

# start postgres up and wait a bit for it so we can create the database and user
# for kong
snapctl start "$SNAP_NAME.postgres"

# add a kong user and database in postgres - note we have to run these through
# the perl5lib-launch scripts to setup env vars properly and we need to loop
# trying to do this because we have to wait for postgres to start up
iter_num=0
MAX_POSTGRES_INIT_ITERATIONS=10
until gosu snap_daemon "$SNAP/bin/perl5lib-launch.sh" "$SNAP/usr/bin/createuser" kong; do
    sleep 1
    iter_num=$(( iter_num + 1 ))
    if [ $iter_num -gt $MAX_POSTGRES_INIT_ITERATIONS ]; then
        echo "failed to create kong user in postgres after $iter_num iterations"
        exit 1
    fi
done
iter_num=0
until gosu snap_daemon "$SNAP/bin/perl5lib-launch.sh" "$SNAP/usr/bin/createdb" kong; do
    sleep 1
    iter_num=$(( iter_num + 1 ))
    if [ $iter_num -gt $MAX_POSTGRES_INIT_ITERATIONS ]; then
        echo "failed to create kong db in postgres after $iter_num iterations"
        exit 1
    fi
done

# stop postgres again in case the security services should be turned off
snapctl stop "$SNAP_NAME.postgres"

# finally, disable and turn off non-default services
# by default, we want the export-*, support-*, device-*, and redis services 
# off.
for svc in export-distro export-client support-notifications support-scheduler support-logging support-rulesengine device-random device-virtual redis; do
    # set the service as off, so that the setting is persistent after a refresh
    # due to snapd bug: https://bugs.launchpad.net/snapd/+bug/1818306
    snapctl set $svc=off
    # also disable the service so it doesn't initially run - note that just 
    # setting the service as off above isn't quite what we want as the install
    # tasks go:
    # - install hook runs
    # - all non-disabled services are started
    # - configure hook runs (thus disabled services turned off)
    # as such, we don't want the services we turn off initially to be started
    # before the configure hook runs as it will be resource intensive for no
    # reason just to start a bunch of services and then immediately try to 
    # stop them afterwards
    snapctl stop --disable "$SNAP_NAME.$svc"
done

# if we are on arm64, disable the security-api-gateway because kong isn't 
# properly supported on arm64 due to incorrect memory pointers used by lua and
# openresty
# see https://github.com/edgexfoundry/blackbox-testing/issues/185 for more 
# details
if [ "$SNAP_ARCH" == "arm64" ]; then
    snapctl set security-api-gateway=off
    snapctl stop --disable "$SNAP_NAME.kong-daemon"
    snapctl stop --disable "$SNAP_NAME.edgexproxy"
fi
